{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "typing.Final 是 Python 3.8 中引入的一个类型注解，用于表示一个变量在定义后不应被重新赋值。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "PI_VALUE_AS_STRING has been modified!\n",
      "3.14\n"
     ]
    }
   ],
   "source": [
    "from typing import Final  \n",
    "  \n",
    "# 定义一个 Final 变量，它应该是一个字符串  \n",
    "PI_VALUE_AS_STRING: Final = \"3.14159\"  \n",
    "  \n",
    "# 尝试修改 Final 变量的值，这在运行时是允许的，但可能会引发类型检查器的警告或错误  \n",
    "try:  \n",
    "    PI_VALUE_AS_STRING = \"3.14\"  # 这在 Python 运行时不会引发错误，但不应该这样做  \n",
    "    print(\"PI_VALUE_AS_STRING has been modified!\")  \n",
    "except TypeError as e:  \n",
    "    # 注意：在纯 Python 运行时，这不会引发 TypeError，但类型检查器可能会发出警告  \n",
    "    print(f\"Type checker might have warned: {e}\")  \n",
    "  \n",
    "# 虽然 PI_VALUE_AS_STRING 在运行时可以被修改，但最好的做法是遵守 Final 的约定，不修改它  \n",
    "print(PI_VALUE_AS_STRING)  # 输出 \"3.14\"，如果上面的赋值语句被执行了  \n",
    "  \n",
    "# 使用 Final 来定义一个配置常量也是常见的用法  \n",
    "SERVER_ADDRESS: Final = \"localhost\"  \n",
    "PORT: Final = 8080  \n",
    "  \n",
    "# 尝试修改这些常量是不好的做法，尽管 Python 允许这样做  \n",
    "# SERVER_ADDRESS = \"example.com\"  # 不应该这样做  \n",
    "# PORT = 80  # 也不应该这样做"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Matched '123seconds': Number=123, Letters=seconds\n",
      "Matched '45minutes': Number=45, Letters=minutes\n",
      "Matched '90hours': Number=90, Letters=hours\n",
      "Matched '7days': Number=7, Letters=days\n",
      "Matched '1week': Number=1, Letters=week\n",
      "No match for 'notamatch'\n"
     ]
    }
   ],
   "source": [
    "import re  \n",
    "from typing import Final  \n",
    "  \n",
    "# 编译正则表达式为 Final 变量  \n",
    "_tf_pattern: Final = re.compile(r\"(\\d+)([A-Za-z]+)\")  \n",
    "  \n",
    "# 定义一个待匹配的字符串列表  \n",
    "strings_to_match = [  \n",
    "    \"123seconds\",  \n",
    "    \"45minutes\",  \n",
    "    \"90hours\",  \n",
    "    \"7days\",  \n",
    "    \"1week\",  \n",
    "    \"notamatch\",  \n",
    "]  \n",
    "  \n",
    "# 遍历字符串列表并尝试匹配  \n",
    "for string in strings_to_match:  \n",
    "    match = _tf_pattern.search(string)  \n",
    "    if match:  \n",
    "        # 如果匹配成功，提取数字和字母部分  \n",
    "        number_part = match.group(1)  \n",
    "        letter_part = match.group(2)  \n",
    "        print(f\"Matched '{string}': Number={number_part}, Letters={letter_part}\")  \n",
    "    else:  \n",
    "        print(f\"No match for '{string}'\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "pybroker",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
